package hn.sigit.logic.ladmshadow;

import hn.sigit.dao.hnd.ladmshadow.ParcelDAO;
import hn.sigit.dao.ladm.party.LA_PartyDAO;
import hn.sigit.model.hnd.administrative.HND_Property;
import hn.sigit.model.hnd.cadastre.HND_Easement;
import hn.sigit.model.hnd.cadastre.HND_Improvement;
import hn.sigit.model.hnd.cadastre.HND_Parcel;
import hn.sigit.model.hnd.ladmshadow.Easement;
import hn.sigit.model.hnd.ladmshadow.Improvement;
import hn.sigit.model.hnd.ladmshadow.Parcel;
import hn.sigit.model.hnd.ladmshadow.Party;
import hn.sigit.model.hnd.ladmshadow.Property;
import hn.sigit.model.hnd.ladmshadow.RRR;
import hn.sigit.model.hnd.ladmshadow.Responsibility;
import hn.sigit.model.hnd.ladmshadow.Restriction;
import hn.sigit.model.hnd.ladmshadow.Right;
import hn.sigit.model.ladm.administrative.LA_RRR;
import hn.sigit.model.ladm.administrative.LA_Responsibility;
import hn.sigit.model.ladm.administrative.LA_Restriction;
import hn.sigit.model.ladm.administrative.LA_Right;
import hn.sigit.model.ladm.party.LA_Party;
import hn.sigit.model.ladm.spatialunit.LA_SpatialUnit;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.vividsolutions.jts.geom.Polygon;

public class ShadowToLADM {
	private static Set<Long> parcelSetToLadmIdSet(Set<Parcel> parcelSet) {
		Set<Long> ladmIdSet = new HashSet<Long>();
		for (Parcel p : parcelSet)
			ladmIdSet.add(p.getLadmId());
		
		return ladmIdSet;
	}
	
	private static HND_Property createNewHndPropertyFromParcel(Parcel parcel, Date timeStamp, boolean applyTimeStampToRRR) {
		Property property = parcel.getProperty();
		
		HND_Parcel newHndParcel = ParcelToHND_Parcel(parcel);
		if ((Polygon) parcel.getShape() != null)
			newHndParcel.setShape( (Polygon) parcel.getShape().clone() );
		newHndParcel.setBeginLifespanVersion(timeStamp);
		
		HND_Property newHndProperty = PropertyToHND_Property(property);
		newHndProperty.setBeginLifespanVersion(timeStamp);
		newHndProperty.setRrr(SetRRR_To_SetLARRR(property.getRrr(), applyTimeStampToRRR, timeStamp));
		
		Set<LA_SpatialUnit> suSet = new HashSet<LA_SpatialUnit>();
		suSet.add(newHndParcel);
		newHndProperty.setSpatialUnits(suSet);
		
		return newHndProperty;
	}
	
	private static Set<Parcel> originalParcelPredecessors(Parcel parcel) {
		Set<Parcel> retval = new HashSet<Parcel>();
		List<Parcel> workingList = new ArrayList<Parcel>();

		workingList = ParcelDAO.loadParcelsByEndLifespanVersion(parcel.getBeginLifespanVersion());
		if (workingList != null && workingList.size() > 0) {
			for (Parcel p : workingList)
				retval.addAll(originalParcelPredecessors(p));
		}
		else
			retval.add(parcel);
		
		return retval;
	}
	
	
	public static HND_Parcel ParcelToHND_Parcel(Parcel parcel) {
		if (parcel == null) return null;
		
		HND_Parcel hndParcel = new HND_Parcel();
		Util.copyMemberValues(parcel, hndParcel, true);
		hndParcel.setShape(parcel.getShape());
		hndParcel.setSuID(0);
		
		hndParcel.setAvailableServices(parcel.getAvailableServices());
		
		hndParcel.getEasements().clear();
		for (Easement e : parcel.getEasements())
			hndParcel.getEasements().add(EasementToHND_Easement(e));
			
		hndParcel.getImprovements().clear();
		for (Improvement i : parcel.getImprovements())
			hndParcel.getImprovements().add(ImprovementToHND_Improvement(i));
		
		//TODO: Usos!!
		
		return hndParcel;
	}
	
	public static HND_Improvement ImprovementToHND_Improvement(Improvement improvement) {
		HND_Improvement hndImprovement = new HND_Improvement();
		Util.copyMemberValues(improvement, hndImprovement, true);
		hndImprovement.setRegistration(improvement.getRegistration());
		
		return hndImprovement;
	}
	
	public static HND_Easement EasementToHND_Easement(Easement easement) {
		HND_Easement hndEasement = new HND_Easement();
		Util.copyMemberValues(easement, hndEasement, true);
		hndEasement.setRegistration(easement.getRegistration());
		
		return hndEasement;
	}

	public static HND_Property PropertyToHND_Property(Property property) {
		if (property == null) return null;
		
		HND_Property hndProperty = new HND_Property();
		Util.copyMemberValues(property, hndProperty, true);
		hndProperty.setuID(0);
		
		hndProperty.setRegistration(property.getRegistration());
		
		return hndProperty;
	}
	
	public static LA_RRR RRRToLA_RRR(RRR rrr) {
		if (rrr == null) return null;
		
		LA_RRR laRrr = null;
		
		if (rrr instanceof Responsibility)
			laRrr = new LA_Responsibility();
		else if (rrr instanceof Right)
			laRrr = new LA_Right();
		else if (rrr instanceof Restriction) {
			laRrr = new LA_Restriction();
			((LA_Restriction) laRrr).setPartyRequired( ((Restriction) rrr).getPartyRequired());
		}

		if (rrr != null) {
			laRrr.setDescription(rrr.getDescription());
			
			LA_Party laParty = LA_PartyDAO.loadPartyByExtParty(rrr.getParty().getExtParty());
			laParty.getRrr().add(laRrr);
			laRrr.setParty( laParty );
			
			
			laRrr.setType(rrr.getType());
			laRrr.setShare(rrr.getShare());
			laRrr.setShareCheck(rrr.getShareCheck());
			laRrr.setTimeSpec(rrr.getTimeSpec());
			
			laRrr.setBeginLifespanVersion(rrr.getBeginLifespanVersion());
			laRrr.setEndLifespanVersion(rrr.getEndLifespanVersion());
			
			laRrr.setrID(0);
		}
		
		return laRrr;
	}

	public static Set<LA_RRR> SetRRR_To_SetLARRR(Set<RRR> rrrSet, boolean applyTimeStamp, Date beginLifespanTimeStamp) {
		if (rrrSet == null) return null;
		
		LA_RRR laRrr;
		Set<LA_RRR> laRrrSet = new HashSet<LA_RRR>();
		for (RRR rrr : rrrSet) {
			if (rrr.getEndLifespanVersion() != null) {
				laRrr = RRRToLA_RRR(rrr);
				if (applyTimeStamp)
					rrr.setBeginLifespanVersion(beginLifespanTimeStamp);
					
				laRrrSet.add(laRrr);
			}
		}
		
		return laRrrSet;
	}
	
	public static LA_Party PartyToLA_Party(Party party) {
		if (party == null) return null;
		
		LA_Party laParty = new LA_Party();
		Util.copyMemberValues(party, laParty, true);
		laParty.setpID(0);
		laParty.setExtParty(party.getExtParty());
		
		return laParty;
	}
}
